package main
/*
 * 经验1： 硬件渲染参数：sdl.CreateRenderer(self.window, -1, sdl.RENDERER_ACCELERATED) 
 * 不能和 window.GetSurface 函数一起用，因此不能用 func (* Surface)Blit ，所以所有图形素材必须转换为 sdl.Texture
 * 
 * */
import (
	"fmt"
	"github.com/veandco/go-sdl2/sdl"
	"os"
    "path"
    "sync"
    "github.com/veandco/go-sdl2/ttf"
    "github.com/veandco/go-sdl2/img"
    "container/list"
    "github.com/veandco/go-sdl2/mix"
    "time"
    "math"
    "math/rand"
)
type Texture struct{
    T *sdl.Texture
    W,H int32
}

func (self *Texture)Load(r *sdl.Renderer,f string) bool{
    solid,err := img.Load( f )
    if err!=nil{
        return false
    }
    self.W= solid.W
    self.H = solid.H
    defer solid.Free()
    self.T,err = r.CreateTextureFromSurface( solid )
    if err!=nil{
        return false
    }
    return true
}

func (self *Texture)Destroy(){
    self.T.Destroy()
    self.T=nil
}

func (self *Texture)drawTextureXY( r *sdl.Renderer, x,y int32 ){
    if self.T!=nil{
        rect := sdl.Rect{ x, y, self.W, self.H }
        r.Copy(self.T,nil,&rect)
    }
}

//sppWin:结构体，存储游戏中的所有全局变量
type appWin struct{
    appdir string
    winTitle string
    winWidth, winHeight int32
    window *sdl.Window
	renderer *sdl.Renderer
	event sdl.Event
	running bool
	err error
    lock *sync.Mutex
    font *ttf.Font
    msgList *list.List
    background,hole,ship,smoke,bz1,bz2,bz3 Texture
    fire,bomb *mix.Music
    Wg sync.WaitGroup
    x,y int32
    hit_dy int32
    start_time time.Time
    bt_win_rect,bt_quit_rect sdl.Rect
    msg map[string]string
    msgTextures map[string]*Texture
    smokePoint *list.List
    effect_hit_dist [2]float32
    effect_wucha [2]float32
    Distance float32
    gun_aim [2]float32
    gun_h,gun_v int32
    report string
    damage float32
    hit_count,effect_count int32
    ready string
    can_fire bool
    last_load time.Time
    win_mode bool
    destroy_list *list.List
    game_id int
}
//addDestroyFunc:把需要手动执行的 Free/Destroy 函数*反方向*存放在 destroy_list 中
func (self *appWin)addDestroyFunc( f interface{} ){
    self.destroy_list.PushFront( f )
}
//appDestroy:按顺序执行放在 destroy_list 中的所有函数
func (self *appWin)appDestroy(){
    i:=0
    for e:=self.destroy_list.Front();e!=nil;e=e.Next(){
        f1,ok := e.Value.( func() )
        if !ok{
            f2,_ := e.Value.( func() error )
            f2()
        }else{
            f1()
        }
        i++
    }
    fmt.Println("释放资源：",i)
}

func (self *appWin)destroyMsgTextures(){
    for _, v := range self.msgTextures {
        v.Destroy()
    }
}
//initVars:初始化各种变量，这些变量可能被改变
func  (self *appWin)initVars(dist float32) {
    self.game_id++
    self.running=true
    self.win_mode=true
    self.msgTextures = make(map[string]*Texture)
    self.msgList = list.New()
    self.msgList.Init()
    self.smokePoint = list.New()
    self.smokePoint.Init()
    self.x = 358
    self.y = 273
    self.Distance = dist
    
    base_hit_dist :=[2]float32{45.0,12.0}
    self.effect_hit_dist[0] = base_hit_dist[0]*2000.0/dist
    self.effect_hit_dist[1] = base_hit_dist[1]*2000.0/dist
    base_wucha := [2]float32{1.0,1.0}
    self.effect_wucha[0] = base_wucha[0]*dist/2000.0
    self.effect_wucha[1] = base_wucha[1]*dist/2000.0
    self.gun_aim[0] = 386
    self.gun_aim[1] = 291
    self.gun_h = 0
    self.gun_v = 0
    self.report=""
    self.damage = 0
    self.hit_count = 0
    self.effect_count = 0
    self.ready = ""
    self.can_fire = true
}
//initWindow:初始化窗口和各种不可变的资源
func (self *appWin)initWindow() int{
    self.appdir = path.Dir(os.Args[0])+"/../"
    self.game_id=1
    self.destroy_list = list.New()
    self.destroy_list.Init()
    
    self.msg =make(map[string]string)
    getLocale(self.msg)
    
    self.winTitle = self.msg["title"] + " https://gitee.com/rocket049"
    self.winWidth = 800
    self.winHeight = 600
    self.bt_win_rect = sdl.Rect{300,568,80,26}
    self.bt_quit_rect = sdl.Rect{388,568,80,26}
    
    sdl.Init(sdl.INIT_EVERYTHING)
    self.addDestroyFunc( sdl.Quit )
    ttf.Init()
    mix.OpenAudio(22050, mix.DEFAULT_FORMAT, 2, 4096)
    if self.win_mode{
        self.window, self.err = sdl.CreateWindow(self.winTitle, sdl.WINDOWPOS_UNDEFINED,
            sdl.WINDOWPOS_UNDEFINED,self.winWidth, self.winHeight, sdl.WINDOW_SHOWN)
        if self.err != nil {
            panic(self.err)
            return 1
        }
    }else{
        self.window, self.err = sdl.CreateWindow(self.winTitle, sdl.WINDOWPOS_UNDEFINED,
            sdl.WINDOWPOS_UNDEFINED,self.winWidth, self.winHeight, sdl.WINDOW_FULLSCREEN)
        if self.err != nil {
            panic(self.err)
            return 1
        }
    }
    self.addDestroyFunc(self.window.Destroy)
    var flag uint32
    flag=sdl.RENDERER_ACCELERATED
	self.renderer, self.err = sdl.CreateRenderer(self.window, -1, flag)
	if self.err != nil {
		flag=sdl.RENDERER_SOFTWARE
		self.renderer, self.err = sdl.CreateRenderer(self.window, -1, flag)
        if self.err != nil {
            panic(self.err)
            return 2
        }
	}
    self.addDestroyFunc( self.renderer.Destroy )
    self.renderer.SetLogicalSize(self.winWidth, self.winHeight)
    self.font, self.err = ttf.OpenFont(self.appdir+"data/ttf/gkai00mp.ttf", 20);
    if self.err != nil {
		panic(self.err)
		return 4
	}
    self.addDestroyFunc( self.font.Close )
    //load texture
    if !self.background.Load(self.renderer,self.appdir+"data/pics/bg2.png") {
		panic(self.appdir+"data/pics/bg2.png")
		return 7
	}
    self.addDestroyFunc( self.background.Destroy )
    if !self.hole.Load(self.renderer,self.appdir+"data/pics/hole1.png") {
		panic(self.appdir+"/data/pics/hole1.png")
		return 9
	}
    self.addDestroyFunc( self.hole.Destroy )
    //ship,smoke,bz1,bz2,bz3
    self.ship.Load(self.renderer,self.appdir+"data/pics/ship1.png")
    self.addDestroyFunc( self.ship.Destroy )
    self.smoke.Load(self.renderer,self.appdir+"data/pics/smoke1.png")
    self.addDestroyFunc( self.smoke.Destroy )
    self.bz1.Load(self.renderer,self.appdir+"data/pics/baozha1.png")
    self.addDestroyFunc( self.bz1.Destroy )
    self.bz2.Load(self.renderer,self.appdir+"data/pics/baozha2.png")
    self.addDestroyFunc( self.bz2.Destroy )
    self.bz3.Load(self.renderer,self.appdir+"data/pics/baozha3.png")
    self.addDestroyFunc( self.bz3.Destroy )
    //load music
    self.fire,_ = mix.LoadMUS(self.appdir+"data/sound/fire.wav")
    self.addDestroyFunc( self.fire.Free )
    self.bomb,_ = mix.LoadMUS(self.appdir+"data/sound/bomb.wav")
    self.addDestroyFunc( self.bomb.Free )
    self.lock = new(sync.Mutex)
    
    return 0
}
//outputTextXY:在(x,y)坐标显示字符串 s，颜色为（r,g,b,255）
func (self *appWin)outputTextXY(s string,x,y int32,r,g,b uint8){
    if len(s)>0 {
        rect := sdl.Rect{x,y,0,0}
        solid, _ := self.font.RenderUTF8Solid(s, sdl.Color{r,g,b, 255})
        defer solid.Free()
        rect.W = solid.W
        rect.H = solid.H
        tx1,_ := self.renderer.CreateTextureFromSurface(solid)
        defer tx1.Destroy()
        self.renderer.Copy(tx1,nil, &rect)
    }
}

func (self *appWin)makeMsgTexture(k string,v string,r,g,b uint8){
    t,ok := self.msgTextures[k]
    if !ok {
        self.msgTextures[k] = new(Texture)
        t,_ = self.msgTextures[k]
    }
    if len(v)>0{
        if t.T!=nil{
            t.T.Destroy()
        }
        solid, _ := self.font.RenderUTF8Solid( v, sdl.Color{r,g,b, 255} )
        defer solid.Free()
        t.W = solid.W
        t.H = solid.H
        t.T,_ =  self.renderer.CreateTextureFromSurface(solid)
        self.msgTextures[k] = t
        //fmt.Println(k,v)
    }
}

func (self *appWin)initMsgTextures(){
    self.ready = self.msg["ready_fire"]
    self.makeMsgTexture("count_fire", fmt.Sprintf(self.msg["count_fire"],self.hit_count) ,0,255,0)
    self.makeMsgTexture("count_hit", fmt.Sprintf(self.msg["count_hit"],self.effect_count,self.damage),
            0,255,0)
    self.makeMsgTexture("distance", fmt.Sprintf(self.msg["distance"],self.Distance),0,255,0)
    self.makeMsgTexture("report", self.report,255,0,0)
    self.makeMsgTexture("ready",self.ready,255,0,0)
}
//drawText:显示msgList内的全部文字
func (self *appWin)drawText(){
    if self.msgTextures["count_fire"].T==nil{
        self.makeMsgTexture("count_fire", fmt.Sprintf(self.msg["count_fire"],self.hit_count) ,0,255,0)
    }
    if self.msgTextures["count_hit"].T==nil{
        self.makeMsgTexture("count_hit", fmt.Sprintf(self.msg["count_hit"],self.effect_count,self.damage),
            0,255,0)
    }
    if self.msgTextures["report"].T==nil{
        self.makeMsgTexture("report", self.report,255,0,0)
    }
    if self.msgTextures["ready"].T==nil{
        self.makeMsgTexture("ready",self.ready,255,0,0)
    }

    //msgRect := sdl.Rect{100,410,0,0}
    //self.outputTextXY(fmt.Sprintf(self.msg["count_fire"],self.hit_count),10,2,0,255,0)
    self.msgTextures["count_fire"].drawTextureXY(self.renderer,10,2)
    //self.outputTextXY(fmt.Sprintf(self.msg["count_hit"],self.effect_count,self.damage),200, 2,0,255,0)
    self.msgTextures["count_hit"].drawTextureXY(self.renderer,200,2)
    //self.outputTextXY(fmt.Sprintf(self.msg["distance"],self.Distance),550, 2,0,255,0)
    self.msgTextures["distance"].drawTextureXY(self.renderer,550,2)
    //self.outputTextXY(self.report,10,26,255,0,0)
    self.msgTextures["report"].drawTextureXY(self.renderer,10,26)
    //self.outputTextXY(self.ready,300,26,255,0,0)
    self.msgTextures["ready"].drawTextureXY(self.renderer,300,26)
    //msgRect.Y +=30
    //for e := self.msgList.Front(); e != nil; e = e.Next() {
        //s,_:=e.Value.(string)
        //self.outputTextXY(s,msgRect.X,msgRect.Y,0,255,255)
        //msgRect.Y +=30
    //}
}
//showSmoke:显示烟柱
func (self *appWin)showSmoke(x,y int32){
    rect := sdl.Rect{self.x+x-10+50,self.y+y-60+15+self.gun_v,20,60}
    self.renderer.Copy(self.smoke.T, nil, &rect)
}
//showAllSmoke:显示所有烟柱
func(self *appWin)showAllSmoke(dy int32){
    for e:=self.smokePoint.Front();e!=nil;e=e.Next() {
        xy,_:=e.Value.([2]int32)
        self.showSmoke(xy[0],xy[1]+dy)
    }
}

//drawTextButton:绘制带文字的长方形按钮
func (self *appWin)drawTextButton(s string, rect *sdl.Rect){
    self.renderer.SetDrawColor(0, 0xff, 0, 0xff)
    self.renderer.DrawRect( rect )
    rect.X+=2
    rect.Y+=2
    rect.W-=4
    rect.H-=4
    solid, _ := self.font.RenderUTF8Solid(s, sdl.Color{0,255,0, 255})
    defer solid.Free()
    tx1,_ := self.renderer.CreateTextureFromSurface(solid)
    defer tx1.Destroy()
    self.renderer.Copy(tx1,nil, rect)
    rect.X-=2
    rect.Y-=2
    rect.W+=4
    rect.H+=4
}
//hitEnemy:击中报告，显示烟柱
func (self *appWin)hitEnemy(x float32){
    id := self.game_id
    sdl.Delay(uint32(self.Distance))
    if id==self.game_id {
        self.lock.Lock()
        self.damage += 50- float32(math.Abs(float64(x)))
        self.effect_count += 1
        //self.makeMsgTexture("count_hit", fmt.Sprintf(self.msg["count_hit"],self.effect_count,self.damage),
        //    0,255,0)
        self.msgTextures["count_hit"].Destroy()
        self.smokePoint.PushFront( [2]int32{ int32(x), 10 } )
        self.report = self.msg["hit"]+fmt.Sprintf(" 误差:%d",int32(x))
        //self.makeMsgTexture("report", self.report,255,0,0)
        self.msgTextures["report"].Destroy()
        self.lock.Unlock()
        mix.VolumeMusic(30)
        self.bomb.Play(1)
    }
}
//missEnemy:未击中报告
func (self *appWin)missEnemy(){
    id := self.game_id
    sdl.Delay(uint32(self.Distance))
    if id == self.game_id {
        self.lock.Lock()
        self.report = self.msg["miss"]
        self.msgTextures["report"].Destroy()
        self.lock.Unlock()
    }
}
//verifyHit:测试射击结果
func (self *appWin)verifyHit(dx,dy int32){
    d_x := float32(dx)+self.effect_wucha[0]*(rand.Float32()-0.5)*2
    d_y := float32(dy)+self.effect_wucha[1]*(rand.Float32()-0.5)*2
    if math.Abs(float64(d_x))<float64(self.effect_hit_dist[0]) && math.Abs(float64(d_y))<float64(self.effect_hit_dist[1]){
        go self.hitEnemy( d_x )
    }else{
        go self.missEnemy()
    }
}
//isOver:检测鼠标位置(x,y)是否在按钮(rect)内
func (self *appWin)isOver(x,y int32,rect *sdl.Rect) bool {
    return x>=rect.X && x<=rect.X+rect.W && y>=rect.Y && y<=rect.Y+rect.H
}
//eventCicle:SDL事件循环，go routine
func (self *appWin)eventCicle() int{
    //var ok bool
    defer self.Wg.Done()
    var btOver string = "none"
    var dt float64
    var dy int32
    var e sdl.Event
    //last_display := self.window.GetCurrentDisplayMode()
    for self.running {
        e = sdl.WaitEvent()
        
		switch t := e.(type) {
            case *sdl.QuitEvent:
                self.lock.Lock()
                self.running = false
                self.lock.Unlock()
            case *sdl.MouseButtonEvent:
            //处理鼠标左键点击
                self.lock.Lock()
                if t.Type == sdl.MOUSEBUTTONUP && t.Button==sdl.BUTTON_LEFT {
                    if self.isOver(t.X,t.Y,&self.bt_win_rect){
                        if self.win_mode{
                            self.window.SetFullscreen(sdl.WINDOW_FULLSCREEN)
                            self.win_mode=false
                        }else{
                            self.window.SetFullscreen(0)
                            self.win_mode=true
                        }
                    } else if self.isOver(t.X,t.Y,&self.bt_quit_rect) {
                        self.running = false
                    } else {
                        btOver = "点在空处"
                    }
                    s :=fmt.Sprintf("MouseButton type:%d id:%d x:%d y:%d button:%d :%s",
                        t.Type, t.Which, t.X, t.Y, t.Button,btOver )
                    self.msgList.PushBack( s )
                    if self.msgList.Len()>4 {
                        self.msgList.Remove(self.msgList.Front())
                    }
                }
            self.lock.Unlock()
            case *sdl.KeyboardEvent:
            self.lock.Lock()
            //处理键盘事件
            /*
    K_RIGHT       = C.SDLK_RIGHT       // "Right" (the Right arrow key (navigation keypad))
    K_LEFT        = C.SDLK_LEFT        // "Left" (the Left arrow key (navigation keypad))
    K_DOWN        = C.SDLK_DOWN        // "Down" (the Down arrow key (navigation keypad))
    K_UP          = C.SDLK_UP          // "Up" (the Up arrow key (navigation keypad))
             * */
                if t.Type == sdl.KEYDOWN {
                    msg :=""
                    switch t.Keysym.Sym {
                        case sdl.K_SPACE:
                            if self.can_fire {
                                self.hit_count += 1
                                self.msgTextures["count_fire"].Destroy()
                                //self.makeMsgTexture("count_fire", fmt.Sprintf(self.msg["count_fire"],self.hit_count) ,0,255,0)
                                dt = float64(time.Since(self.start_time))/1000000000
                                dy = int32(math.Sin( math.Pi*dt/6.0)*30)
                                self.hit_dy = dy
                                //self.smokePoint.PushFront( [2]int32{int32(self.gun_aim[0])-self.x,
                                    //int32(self.gun_aim[1])-(self.y+self.hit_dy+self.gun_v)} )
                                self.verifyHit(int32(self.gun_aim[0])-(self.x+50),
                                  int32(self.gun_aim[1])-(self.y+self.hit_dy+self.gun_v+15))
                                msg = fmt.Sprintf("xy误差：%d,%d",int32(self.gun_aim[0])-(self.x+50),
                                  int32(self.gun_aim[1])-(self.y+self.hit_dy+self.gun_v+15))
                                //fmt.Println(int32(self.gun_aim[0])-(self.x+50),
                                  //int32(self.gun_aim[1])-(self.y+self.hit_dy+self.gun_v+15))
                                go self.playFire()
                                self.can_fire = false
                                self.last_load = time.Now()
                            }
                        case sdl.K_RIGHT:
                            //msg = "向右转down"
                            self.gun_h = -3
                        case sdl.K_LEFT:
                            //msg = "向左转down"
                            self.gun_h = 3
                        case sdl.K_DOWN:
                            //msg = "调低炮口down"
                            self.gun_v -=1
                        case sdl.K_UP: 
                            //msg = "调高炮口down"
                            self.gun_v +=1
                    }
                    if len(msg)!=0 {
                        self.msgList.PushBack( msg )
                        if self.msgList.Len()>4 {
                            self.msgList.Remove(self.msgList.Front())
                        }
                    }
                } else if t.Type == sdl.KEYUP {
                    msg :=""
                    switch t.Keysym.Sym {
                        case sdl.K_RIGHT:
                            //msg = "向右转up"
                            self.gun_h = 0
                        case sdl.K_LEFT:
                            //msg = "向左转up"
                            self.gun_h = 0
                        case sdl.K_F11:
                            if self.win_mode{
                                self.window.SetFullscreen(sdl.WINDOW_FULLSCREEN)
                                self.win_mode=false
                            }else{
                                self.window.SetFullscreen(0)
                                self.win_mode=true
                            }
                        case sdl.K_ESCAPE:
                            self.running = false
                    }
                    if len(msg)!=0 {
                        self.msgList.PushBack( msg )
                        if self.msgList.Len()>4 {
                            self.msgList.Remove(self.msgList.Front())
                        }
                    }
                }
            self.lock.Unlock()
        }
    }
	return 0
}
//playFire:播放开炮声音
func (self *appWin)playFire(){
    mix.VolumeMusic(200)
    self.fire.Play(1)
}
//updateWin:循环绘制画面，每个循环30毫秒
func (self *appWin)updateWin(){
    bg_rect := sdl.Rect{0,0,800,600}
    //var dx int32=-1
    var dt float64
    var dy int32
    ship_rect := sdl.Rect{self.x,0,100,29}
    aim_rect := sdl.Rect{int32(self.gun_aim[0])-2,int32(self.gun_aim[1])-2,4,4}
    self.start_time=time.Now()
    for self.running {
        self.lock.Lock()
        dt = float64(time.Since(self.start_time))/1000000000
        dy = int32(math.Sin( math.Pi*dt/6.0)*30)
        
        ship_rect.Y = self.y + dy + self.gun_v
        bg_rect.Y = dy + self.gun_v
        ship_rect.X += self.gun_h - 1
        bg_rect.X += self.gun_h - 1
        self.x = ship_rect.X
        
        self.renderer.SetDrawColor(0, 0, 0, 255)
        self.renderer.Clear()
        self.renderer.Copy(self.background.T,nil,&bg_rect)
        self.renderer.Copy(self.ship.T,nil,&ship_rect)
        self.showSmoke(ship_rect.X,ship_rect.Y)
        self.showAllSmoke(dy)
        
        self.renderer.Copy(self.hole.T,nil,nil)
        
        self.drawText()
        if self.win_mode {
            self.drawTextButton(self.msg["fs"],&self.bt_win_rect)
        }else{
            self.drawTextButton(self.msg["win"],&self.bt_win_rect)
        }
        self.drawTextButton(self.msg["quit"],&self.bt_quit_rect)
        
        self.renderer.SetDrawColor(255, 0, 0, 255)
	    self.renderer.FillRect(&aim_rect)
        if self.damage>100{
            self.damageShip(&ship_rect)
            self.lock.Unlock()
            break
        }
        self.renderer.Present()
        //self.last_load 变量在eventCicle中修改，因此放在self.lock.Unlock前
        dt = float64(time.Since(self.last_load))/1000000000
        if (self.x-int32(self.gun_aim[0]))*(self.x-int32(self.gun_aim[0]))>250*250{
            self.outputTextXY( self.msg["fail"],320,200,255,0,0)
            self.renderer.Present()
            self.running = false
            sdl.Delay(3000)
        }
        
        if dt<5{
            if self.ready == self.msg["ready_fire"]{
                self.ready = self.msg["loading"]
                self.makeMsgTexture("ready",self.ready,255,0,0)
            }
        }else{
            if self.ready == self.msg["loading"] {
                self.ready = self.msg["ready_fire"]
                self.makeMsgTexture("ready",self.ready,255,0,0)
            }
            self.can_fire = true
        }
        self.lock.Unlock()
        sdl.Delay(30)
    }
}

func (self *appWin)damageShip(rect *sdl.Rect){
    self.outputTextXY(self.msg["long_damage"],320,200,255,0,0)
    self.renderer.Present()
    self.renderer.Copy(self.bz1.T,nil,rect)
    self.renderer.Present()
    self.bomb.Play(1)
    sdl.Delay(1000)
    self.renderer.Copy(self.bz2.T,nil,rect)
    self.renderer.Present()
    self.bomb.Play(1)
    sdl.Delay(1000)
    self.renderer.Copy(self.bz3.T,nil,rect)
    self.renderer.Present()
    self.bomb.Play(1)
    sdl.Delay(3000)
    self.running = false
}
//askTodo:询问下一步
func (self *appWin)askTodo() int{
    self.renderer.SetDrawColor(0, 0, 0, 255)
    self.renderer.Clear()
    bt_ask1 := sdl.Rect{300,200,250,30}
    bt_ask2 := sdl.Rect{300,250,250,30}
    bt_ask3 := sdl.Rect{300,300,250,30}
    bt_quit := sdl.Rect{300,350,250,30}
    self.outputTextXY(fmt.Sprintf(self.msg["success"],self.Distance),270, 150,255, 0, 0)
    /*self.draw_text_button(self.screen,bt2,msg['fire_dist'].format(dist-1000))
        self.draw_text_button(self.screen,bt3,msg['fire_dist'].format(dist))
        self.draw_text_button(self.screen,bt4,msg['fire_dist'].format(dist+1000))*/
    self.drawTextButton(fmt.Sprintf(self.msg["fire_dist"],self.Distance-1000),&bt_ask1)
    self.drawTextButton(fmt.Sprintf(self.msg["fire_dist"],self.Distance),&bt_ask2)
    self.drawTextButton(fmt.Sprintf(self.msg["fire_dist"],self.Distance+1000),&bt_ask3)
    self.drawTextButton(self.msg["quit"],&bt_quit)
    self.renderer.Present()
    var e sdl.Event
    var selecting bool=true
    for selecting {
        e = sdl.WaitEvent()
		switch t := e.(type) {
            case *sdl.QuitEvent:
                selecting = false
            case *sdl.MouseButtonEvent:
            //处理鼠标左键点击
                if t.Type == sdl.MOUSEBUTTONUP && t.Button==sdl.BUTTON_LEFT {
                    if self.isOver(t.X,t.Y,&bt_ask1){
                        return 1
                    } else if self.isOver(t.X,t.Y,&bt_ask2){
                        return 2
                    } else if self.isOver(t.X,t.Y,&bt_ask3){
                        return 3
                    } else if self.isOver(t.X,t.Y,&bt_quit){
                        return 0
                    }
                }
        }
    }
    return 0
}
//main:程序入口
func main() {
    var app1 appWin
    var ret int
    app1.initVars(4000)
    app1.initWindow()
    for{
        app1.Wg.Add(1)
        app1.initMsgTextures()
        go app1.eventCicle()
        app1.updateWin()
        ret = app1.askTodo()
        app1.destroyMsgTextures()
        switch ret {
            case 0:
                goto outhere
            case 1:
                app1.initVars(app1.Distance-1000)
            case 2:
                app1.initVars(app1.Distance)
            case 3:
                app1.initVars(app1.Distance+1000)
        }
    }
    outhere:
    app1.Wg.Wait()
    app1.appDestroy()
    os.Exit(0)
}
